﻿# -*- coding: utf-8 -*-
import datetime

from date_help import date_help
from openerp import models, fields, api, _
from openerp.exceptions import Warning


class bc_contract(models.Model):
    _name = 'bc.contract'

    name = fields.Char()
    name2 = fields.Char()
    company_id = fields.Many2one('res.company', default=lambda self: self.env.user.company_id)
    bussines_id = fields.Many2one('bc.bussines')
    startdate = fields.Date()
    enddate = fields.Date()
    rentdate = fields.Date()
    state = fields.Selection([('draft', u'草稿'), ('audit', u'审核'), ('rent', u'退租'), ('close', u'关闭'), ])
    remark = fields.Text()
    audit_uid = fields.Many2one('res.users')
    audit_date = fields.Datetime()

    contract_detail_ids = fields.One2many('bc.contract.detail', 'contract_id')

    @api.one
    @api.constrains('startdate', 'enddate')
    def _check_date(self):
        if self.startdate > self.enddate:
            raise ValueError(_("开始时间不能大于结束时间!"))

    @api.one
    @api.constrains('rentdate', 'enddate')
    def _check_date(self):
        if self.rentdate >= self.enddate:
            raise ValueError(_("退租日期不能大于等于结束日期!"))

    @api.model
    def create(self, vals):
        vals['name'] = self.env['ir.sequence'].get('bc.contract')
        vals['state'] = 'draft'
        return super(bc_contract, self).create(vals)
    
    # 僅能刪除草稿狀態的資料
    @api.multi
    def unlink(self):
       if self.state not in ('draft') :
          raise Warning(_('state {0} can not be delete'.format(self.state)))
       return super(bc_contract,self).unlink()    

    ##############################################################################################################
    # 反审核
    #
    ##############################################################################################################
    @api.model
    def btn_unaudit(self):
        self.write({'state': 'draft', 'audit_uid': False, 'audit_date': False})
        return True

    ##############################################################################################################
    # 审核,
    # 1.第一步生成所有收款计划到bc.contract.period ,第二步,拷贝第一期的记录到planbill
    ##############################################################################################################
    def create_audit_period(self):
        obj_period = self.env['bc.contract.period']

        # 1.如果数据已经生成,则不执行
        if obj_period.has_contract_id(self.id):
            return

        # 2,循环合同明细,创建收款计划
        for obj in self.contract_detail_ids:
            if obj.expenseitem_id.expense_Type == 'period':
                # 如果是周期收款
                startdate = date_help.str_to_date(self.startdate)
                enddate = date_help.str_to_date(self.enddate)
                obj_period.create_vals(obj, 1, startdate, enddate)
            else:
                # 如果是一次性收款
                vals = {'contract_detail_id': obj.id,
                        'index': 1,
                        'startdate': obj.startdate,
                        'enddate': obj.enddate,
                        'decmoney': obj.price * obj.interval}
                obj_period.create(vals)

    # 创建账单,生成第一期的数据
    def create_audit_planbill(self):

        obj_planbill = self.env['bc.planbill']

        if obj_planbill.has_contract_audit(self.id):
            return

        vals = {'bussines_id': self.bussines_id.id,
                'contract_id': self.id,
                'dttrans': datetime.datetime.utcnow(),
                'source': 'contract_audit',
                'planbill_detail_ids': self.get_audit_planbill_detail(),}

        obj_planbill.create(vals)

    def get_audit_planbill_detail(self):
        obj_period = self.env['bc.contract.period']
        res = []
        for obj in obj_period.get_period_one(self.id):
            res.append(((0, False,
                         {'resource_id': obj.resource_id.id,
                          'expenseitem_id': obj.expenseitem_id.id,
                          'startdate': obj.startdate,
                          'enddate': obj.enddate,
                          'decmoney': obj.decmoney,
                          'contract_period_id': obj.id,
                          })))
        return res

    @api.model
    def btn_audit(self):
        # 1.审核产生收款计划
        self.create_audit_period()
        # 2.审核产生账单
        self.create_audit_planbill()
        # 3.更改状态
        self.write({'state': 'audit', 'audit_uid': self.env.user.id, 'audit_date': datetime.datetime.utcnow()})
        return True

    ##############################################################################################################
    # 退租
    # 自动产生多收的钱,生成负数记录
    ##############################################################################################################
    def create_rent_planbill(self):
        obj_planbill = self.env['bc.planbill']

        if obj_planbill.has_rent(self.id):
            return

        vals = {'bussines_id': self.bussines_id.id,
                'contract_id': self.id,
                'dttrans': datetime.datetime.utcnow(),
                'source': 'contract_rent',
                'planbill_detail_ids': self.get_rent_planbill_detail(),}

        obj_planbill.create(vals)

    def get_rent_planbill_detail(self):
        obj_planbill_detail = self.env['bc.planbill.detail']

        rentdate = date_help.add_day(self.rentdate, 1)
        obj_details = obj_planbill_detail.get_end_data(self.id, rentdate)

        if not (obj_details):
            return

        res = []
        for obj in self.contract_detail_ids:
            if obj.expenseitem_id.expense_Type == 'deposit':
                # 如果是(押金)收取则全部退掉
                res.append(((0, False, {'resource_id': obj.resource_id.id,
                                        'expenseitem_id': obj.expenseitem_id.id,
                                        'startdate': self.startdate,
                                        'enddate': self.enddate,
                                        'decmoney': -1 * obj.price,
                                        })))
            elif obj.expenseitem_id.expense_Type == 'period':
                # 如果是账期生成的,则根据contract_period_id,找到对应的bc.planbill.detail的id的_end_date
                _end_date = None
                for obj_detail in obj_details:
                    if obj_detail.contract_period_id.contract_detail_id.id == obj.id:
                        _end_date = obj_detail.enddate

                if not (_end_date):
                    continue

                res.append(((0, False,
                             {'resource_id': obj.resource_id.id,
                              'expenseitem_id': obj.expenseitem_id.id,
                              'startdate': rentdate,
                              'enddate': _end_date,
                              'decmoney': -1 * date_help.get_moeny(obj.unit, obj.price, rentdate,
                                                                   _end_date),})))

        return res

    @api.model
    def btn_rent(self):
        self.create_rent_planbill()
        self.write({'state': 'rent'})
        return True
